/**
 * 
 */
package neptune.manager.validator.rules.topology;

import java.util.ArrayList;

import neptune.manager.model.topology.Link;
import neptune.manager.model.topology.Topology;
import neptune.manager.utils.Logger.MessageType;
import neptune.manager.validator.ValidatorResult;
import neptune.manager.validator.ValidatorRule;
import neptune.manager.validator.Validator.Status;

/**
 * @author Roberto Bifulco [RobertoBifulco.it] [info@robertoBifulco.it]
 * 
 */
public class LinkSingleEndPointForIfaceRule extends ValidatorRule<Topology> {

	@Override
	public String getName() {
		return "LinkSingleEndPointForIfaceRule";
	}

	@Override
	protected ValidatorResult validationAlgorithm(Topology toValidate,
			ValidatorResult result) {
		/*
		 * Questa lista conterra' identificativi opportunamente costruiti, del
		 * tipo: nodeName:interfaceName. Questo per indentificare univocamente,
		 * in modo semplice, una interfaccia al livello della topologia.
		 */
		ArrayList<String> occupiedInterfaces = new ArrayList<String>(0);
		ArrayList<String> occupingLink = new ArrayList<String>(0);

		for (Link link : toValidate.getLinks()) {

			result.getLog().addMessage("Analyzing link '" + link.getId() + "'",
					MessageType.NORMAL);

			if (link.getSource() != null) {
				result.getLog().addMessage("Analyzing source.",
						MessageType.NORMAL);
				String netIf = link.getSource().getNodeId() + ":"
						+ link.getSource().getInterfaceId();

				if (occupiedInterfaces.contains(netIf)) {
					result.setStatus(Status.ERROR);
					result.getLog().addMessage(
							"Network interface '"
									+ link.getSource().getInterfaceId()
									+ "' in node '"
									+ link.getSource().getNodeId()
									+ "' is already in use from link '"
									+ occupingLink.get(occupiedInterfaces
											.indexOf(netIf)) + "'",
							MessageType.ERROR);
				} else {
					occupiedInterfaces.add(netIf);
					occupingLink.add(link.getId());
				}
			}

			if (link.getDestination() != null) {
				result.getLog().addMessage("Analyzing destination.",
						MessageType.NORMAL);
				String netIf = link.getDestination().getNodeId() + ":"
						+ link.getDestination().getInterfaceId();

				if (occupiedInterfaces.contains(netIf)) {
					result.setStatus(Status.ERROR);
					result.getLog().addMessage(
							"Network interface '"
									+ link.getDestination().getInterfaceId()
									+ "' in node '"
									+ link.getDestination().getNodeId()
									+ "' is already in use from link '"
									+ occupingLink.get(occupiedInterfaces
											.indexOf(netIf)) + "'",
							MessageType.ERROR);
				} else {
					occupiedInterfaces.add(netIf);
					occupingLink.add(link.getId());
				}
			}

		}

		return result;
	}

}
